package com.jdcjk.chat;


import android.os.Environment;

import com.jdcjk.MainApp;
import com.jdcjk.util.L;
import com.jdcjk.util.TimeUtils;

import org.greenrobot.eventbus.EventBus;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.XMPPConnection;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by dong on 2016/5/9.
 * 即时通讯连接监听类
 */
public class OpenFireConnectionListener implements ConnectionListener {
    private final String TAG = OpenFireConnectionListener.class.getSimpleName();
    private Timer timer = new Timer();
    private int waiting = 0;
    public static final String restartLogin = "restartLogin";

    // 连接过后回调
    @Override
    public void connected(XMPPConnection connection) {
        L.i(TAG, "connectionClosedOnError:进行Openfire服务端连接 ");
        for (AppListener appListener : MainApp.appListeners) {
            appListener.onNetWorkStatusChange(true);
        }
    }

    // 认证过后回调
    @Override
    public void authenticated(XMPPConnection connection, boolean resumed) {
        L.i(TAG, "connectionClosedOnError:进行Openfire服务端认证 ");
        for (AppListener appListener : MainApp.appListeners) {
            appListener.onNetWorkStatusChange(true);
        }
    }

    // 正常断开
    @Override
    public void connectionClosed() {
        L.i(TAG, "connectionClosedOnError:与Openfire服务端连接断开 ");
        // 断开连接
        OpenFireConnectionManager.getInstance().disconnect();
        for (AppListener appListener : MainApp.appListeners) {
            appListener.onNetWorkStatusChange(false);
        }
    }

    // 异常断开
    @Override
    public void connectionClosedOnError(Exception arg0) {
        L.i(TAG, "connectionClosedOnError:与Openfire服务端连接异常断开 ");
        // 判斷為帳號已被登錄
        boolean error = arg0.getMessage().contains("<stream:error><conflict xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error>");
        // 重新连接服务器
        timer.schedule(new timeTask(), waiting() * 1000L);
        // 移除监听
        if (MainApp.openFireConnectionListener != null) {
            OpenFireConnectionManager.getInstance().getXMPPTcpConnection().removeConnectionListener(MainApp.openFireConnectionListener);
        }
        if (MainApp.chatManager != null && MainApp.chatManagerListener != null) {
            MainApp.chatManager.removeChatListener(MainApp.chatManagerListener);
        }
        if (MainApp.chat != null && MainApp.chatMessageListener != null) {
            MainApp.chat.removeMessageListener(MainApp.chatMessageListener);
        }
        if (MainApp.roster != null) {
            MainApp.roster.removeRosterListener(MainApp.rosterListener);
            MainApp.roster.removeRosterLoadedListener(MainApp.rosterLoadedListener);
        }
        //释放连接
        OpenFireConnectionManager.getInstance().release();
        if (!error) {
            // 重新连接服务器
            timer.schedule(new timeTask(), waiting() * 1000L);
        } else {
            //关闭重新连接服务器线程
            timer.cancel();
            // 账号被登陆
            //通过EventBus发出信息到activity，弹出重启dialog
            String message = restartLogin;
            EventBus.getDefault().post(message);
        }
    }

    // 正在重新连接
    @Override
    public void reconnectingIn(int arg0) {
        L.i(TAG, "connectionClosedOnError:正在重新连接Openfire服务端 ");
    }

    // 重新连接失败
    @Override
    public void reconnectionFailed(Exception arg0) {
        L.i(TAG, "connectionClosedOnError:重新连接Openfire服务端失败 ");
//		// 断开连接
//		OpenFireConnectionManager.getInstance().disconnect();
//		// 重连服务器
//		timer.schedule(new timeTask(), waiting() * 1000L);
    }

    // 重新连接成功
    @Override
    public void reconnectionSuccessful() {
        L.i(TAG, "connectionClosedOnError:重新连接Openfire服务端成功 ");
        for (AppListener appListener : MainApp.appListeners) {
            appListener.onNetWorkStatusChange(false);
        }
//		MainApp.getInstance().getOfflineMessages();
    }

    /**
     * 一直无网络情况下，尝试登陆的延时时间随次数增加而增加，大于20次后，延时固定为10分钟重连一次（节省电量）。
     *
     * @return int 返回延时时间（s）
     */

    private int waiting() {
        if (waiting > 20) {
            return 600;
        }
        if (waiting > 13) {
            return 300;
        }
        return waiting <= 7 ? 10 : 60;
    }

    class timeTask extends TimerTask {
        @Override
        public void run() {
            //获得时间当前天数
            String time = TimeUtils.getTime(TimeUtils.getCurrentTimeInLong(), TimeUtils.DATE_FORMAT_DATE);
            String nowTime = TimeUtils.getTime(TimeUtils.getCurrentTimeInLong(), TimeUtils.DEFAULT_DATE_FORMAT);
            String fileName = "jdcjk-connection-" + time + ".log";
            if (OpenFireConnectionManager.getInstance().getXMPPTcpConnection() != null && OpenFireConnectionManager.getInstance().getXMPPTcpConnection().isAuthenticated()) {
                waiting = 0;
                cancel();
                String message = nowTime + "Openfire断线重连成功";
                writeFileToSD(fileName, message);
            } else {
                String message = nowTime + "Openfire断线重连";
                writeFileToSD(fileName, message);
                OpenFireConnectionManager.getInstance().getXMPPTcpConnection();
                OpenFireConnectionManager.getInstance().connect();
                waiting++;
                timer.schedule(new timeTask(), waiting() * 1000L);
            }
        }
    }

    private void writeFileToSD(String fileName, String message) {
        String sdStatus = Environment.getExternalStorageState();
        if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) {
            return;
        }
        try {
            String pathName = "/sdcard/jdcjk/";
            File path = new File(pathName);
            File file = new File(pathName + fileName);
            if (!path.exists()) {
                path.mkdir();
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream stream = new FileOutputStream(file, true);
            byte[] buf = message.getBytes();
            stream.write(buf);
            stream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
